﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Windows;
using System.Collections.Specialized;
using Microsoft.Xna.Framework;

namespace Pavilion.DesignerTool
{
    public class AnimationLayer : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public Vector2 PositionOnBoard { get; set; }
        public NotifiableCollection<ResourceData> AnimationResourceCollection { get; private set; }
        public ResourceData CurrentAnimationResource { get { return _currentResource; } set { SetCurrentAnimationResource(value); } }
        public AnimationData CurrentAnimationData { get { return _currentAnimationData; } set { SetCurrentAnimationData(value); } }
        public FrameData CurrentFrameData { get { return _currentFrame; } set { SetCurrentFrameData(value); } }
        public Thickness OffsetMargin { get { return _offsetMargin; } set { _offsetMargin = value; OnPropertyChanged("OffsetMargin"); } }
        public int Offset { get { return _offset; } set { SetOffset(value); } }
        public float SpeedDistance { get; set; }
        public bool IsEnabled { get { return _isEnabled; } set { SetIsEnabled(value); } }
        public NotifiableCollection<AnimationData> AnimationDataCollection { get { return (CurrentAnimationResource == null) ? null : CurrentAnimationResource.AnimationDataCollection; } }
        public NotifiableCollection<FrameData> FrameDataCollection { get { return (CurrentAnimationData == null) ? null : CurrentAnimationData.FrameDataCollection; } }

        private ResourceData _currentResource;
        private AnimationData _currentAnimationData;
        private FrameData _currentFrame;
        private bool _isEnabled;
        private int _offset;
        private Thickness _offsetMargin;

        public AnimationLayer(NotifiableCollection<ResourceData> animationResourceCollection)
        {
            this.AnimationResourceCollection = animationResourceCollection;

            IsEnabled = true;
            OffsetMargin = new Thickness();
            PositionOnBoard = new Vector2(200, 100);
        }

        public void AddNewFrame()
        {
            if (CurrentAnimationData != null)
                CurrentAnimationData.AddNewFrameData();
        }

        public void AddFrames(List<Frame> frames)
        {
            if (CurrentAnimationData != null)
            {
                foreach (Frame frame in frames)
                    CurrentAnimationData.AddNewFrameData(frame);
            }
        }

        public void PasteFrames(IEnumerable<Frame> frames)
        {
            if (CurrentAnimationData != null)
            {
                foreach (Frame frame in frames)
                    CurrentAnimationData.PasteNewFrameData(frame);
            }
        }

        public void RemoveFrame(FrameData frameData)
        {
            CurrentAnimationData.FrameDataCollection.Remove(frameData);
        }

        private void ResetCurrentAnimation()
        {
            if (AnimationDataCollection.Count > 0)
                CurrentAnimationData = AnimationDataCollection[0];
            else
                CurrentAnimationData = null;
        }

        private void SetCurrentAnimationResource(ResourceData value)
        {
            _currentResource = value;

            OnPropertyChanged("AnimationDataCollection");
            ResetCurrentAnimation();
        }

        private void SetCurrentAnimationData(AnimationData value)
        {
            if (_currentAnimationData == value)
                return;

            _currentAnimationData = value;
            OnPropertyChanged("CurrentAnimationData");

            if (CurrentAnimationData != null && CurrentAnimationData.FrameDataCollection.Count > 0)
                CurrentFrameData = CurrentAnimationData.FrameDataCollection[0];
            else
                CurrentFrameData = null;

            OnPropertyChanged("FrameDataCollection");
        }

        private void SetCurrentFrameData(FrameData value)
        {
            if (_currentFrame == value)
                return;

            _currentFrame = value;
            OnPropertyChanged("CurrentFrameData");
        }

        private void SetIsEnabled(bool value)
        {
            _isEnabled = value;
            OnPropertyChanged("IsEnabled");

            if (value == false || CurrentAnimationData == null)
                CurrentFrameData = null;
            else if (CurrentAnimationData.FrameDataCollection.Count > 0)
                CurrentFrameData = CurrentAnimationData.FrameDataCollection[0];
        }

        private void SetOffset(int value)
        {
            _offset = value;
            OffsetMargin = new Thickness(Offset * FrameRange.IndexWidth, 0, 0, 0);
            OnPropertyChanged("Distance");
        }

        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
